package com.droid.mvvmlib.concurrent;

import com.droid.base.concurrent.ThreadExecutor;
import com.droid.mvvmlib.log.Logcat;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import androidx.annotation.NonNull;

/**
 * 提供监控与打印日志功能
 */
public class ThreadExecutorObservable extends ThreadExecutor {

    private static final String TAG = "ThreadExecutorObservable";
    private String mName;

    ThreadExecutorObservable(int corePoolSize, int maxPoolSize, int queueSize, String name) {
        super(corePoolSize, maxPoolSize, name, queueSize);
        mName = name;
        Logcat.i(TAG, "Create thread executor: " + corePoolSize + ", " + maxPoolSize + ", "
                + queueSize + ", " + name);
    }

    @NonNull
    @Override
    public <T> Future<T> submit(Callable<T> task) {
        observeState();
        return super.submit(task);
    }

    @NonNull
    @Override
    public Future<?> submit(Runnable task) {
        observeState();
        return super.submit(task);
    }

    @Override
    public Future<?> submit(Runnable task, long delayMs) {
        observeState();
        return super.submit(task, delayMs);
    }

    @Override
    public <T> Future<T> submit(Callable<T> task, OnResultListener<T> listener) {
        observeState();
        return super.submit(task, listener);
    }

    private void observeState() {
        int queueSize = getQueue().size();
        int activeCount = getActiveCount();

        // 监控容量与正在执行的线程数，Queue 满了后会创建新的线程直到等于 Maximum Pool Size
        if ((getQueue().remainingCapacity() <= 0) && (activeCount >= getMaximumPoolSize())) {
            Logcat.e(TAG, "ThreadExecutor queue is full, the task may be drop. Active count: " + activeCount
                    + ", queue size" + queueSize + ", name: " + mName);
        } else if ((getQueue().remainingCapacity() <= 0) && (activeCount >= getCorePoolSize())) {
            Logcat.w(TAG, "ThreadExecutor has too many active tasks. Active count: " + activeCount
                    + ", maximum pool size: " + getMaximumPoolSize() + ", queue size: " + queueSize
                    + ", name: " + mName);
        } else if ((queueSize > 0) && (activeCount >= getCorePoolSize())) {
            Logcat.w(TAG, "ThreadExecutor use queue. Active count: " + activeCount
                    + ", queue size" + queueSize + ", name: " + mName);
        }

        Logcat.d(TAG, "queue size: " + queueSize + ", active count: " + activeCount
                + ", completed count: " + getCompletedTaskCount() + ", name: " + mName);
    }
}